package com.fitapp;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class LightSensorSportArtsActivity extends Activity
{
	// The duration of one exercise iteration. Currently the user has to hold
	// the press up for 0 seconds. May a few seconds for a harder training
	private static final int WAIT_SEC = 0;

	// For two light borders. To force the User to do a complete exercise
	// iteration.
	// If you put the same value, it will be the same border. Finally there is
	// only one border.
	// May the Developer, who implements this class, needs a more sensible
	// recognition of light. Then he could implement two borders
	// After a long discussion, we dicided to implement one border.
	// Enter the values IN PERCENT
	private static final int MAX_CALIBRATE = -15;
	private static final int MIN_CALIBRATE = 15;

	// Sensor variables
	private double light_limit_min;
	private double light_limit_max;
	private int countPressUp;
	private int countSize;
	private boolean calibratedAlready;
	private long lastUpdateTime;
	private double lastDataLightSensor;
	private double calibrateValue;
	private String currentSportart;
	private int totalCount;
	private boolean start;
	private int reachedAmount;
	private int intendedAmount;
	private int exerciseAmount;
	private boolean change;
	private double time;
	private boolean backWasClicked = false;

	// MediaPlayer
	private MediaPlayer mPlayer;

	// Database variables
	private DatabaseHelper helper;
	private SQLiteDatabase db;
	private Cursor cursor;

	// Light Sensor
	private SensorManager mySensorManager;
	private Sensor lightSensor;

	// Gui variables
	private TextView textHead;
	private TextView textDesc;
	private TextView textShowCount;

	private ImageView imageWorkout;
	private Toast lastToast;
	private Button btnStart;
	private Button btnStop;
	private TextView tvLightAmount;

	private boolean wroteInDB;

	@Override
	public void onCreate( Bundle savedInstanceState )
	{
		super.onCreate( savedInstanceState );
		setContentView( R.layout.activity_light_sensor_sportarts );

		// Init gui variables
		textShowCount = (TextView) findViewById( R.id.ShowCount );
		textHead = (TextView) findViewById( R.id.textHead );
		textDesc = (TextView) findViewById( R.id.textDesc );
		imageWorkout = (ImageView) findViewById( R.id.ivWorkoutHelp );
		btnStart = (Button) findViewById( R.id.btnLightStart );
		tvLightAmount = (TextView) findViewById( R.id.tvLightAmount );
		btnStop = (Button) findViewById( R.id.btnLightStop );
		btnStart.setTextColor( Color.GREEN );
		btnStop.setTextColor( Color.GRAY );

		mySensorManager = (SensorManager) getSystemService( SENSOR_SERVICE );
		lightSensor = mySensorManager.getDefaultSensor( Sensor.TYPE_LIGHT );

		// Init all variables
		lastUpdateTime = 0;
		countPressUp = 0;
		countSize = 0;
		lastDataLightSensor = 0;
		calibrateValue = 0;
		light_limit_min = 0;
		light_limit_max = 0;
		time = 0;
		calibratedAlready = false;
		btnStart.setEnabled( true );
		btnStop.setEnabled( false );
		helper = new DatabaseHelper( this );
		db = helper.getReadableDatabase( );
		change = false;
		wroteInDB = false;
		currentSportart = "";

		Bundle extras = getIntent( ).getExtras( );

		// Select sports art
		if( extras != null )
		{
			currentSportart = extras.getString( "modus" );
		}
		else
		{
			// Default is press ups
			showToast( "You training press ups now" );
		}

		// Switch gui between sports art
		if( currentSportart.equals( DatabaseHelper.TYPE_SITUP ) )
		{
			currentSportart = DatabaseHelper.TYPE_SITUP;
			textHead.setText( DatabaseHelper.TYPE_SITUP );
			textDesc.setText( "Drop the Device below your head and touch it during the exercise." );
			imageWorkout.setImageResource( R.drawable.situp_help_trans );
		}
		else
		{
			// Default
			currentSportart = DatabaseHelper.TYPE_PRESSUP;
			textHead.setText( DatabaseHelper.TYPE_PRESSUP );
			textDesc.setText( "Drop the Device next to you and touch it with your head during the exercise." );
			imageWorkout.setImageResource( R.drawable.pressup_help_trans );
		}

		if( lightSensor != null )
		{
			// Signals the activation of the Light Sensor
			showToast( "Light Sensor is activated" );
			mySensorManager.registerListener( LightSensorListener, lightSensor, SensorManager.SENSOR_DELAY_NORMAL );
		}
		else
		{
			showToast( "There is no Light Sensor" );
			Intent i = new Intent( LightSensorSportArtsActivity.this, MainActivity.class );
			startActivity( i );
		}
		dataFromDatabase( );
	}

	// The System calls the method when the activity ist fisishing or being
	// destroyed by the system
	public void onDestroy()
	{
		super.onDestroy( );
		if( db != null && helper != null )
		{
			helper.close( );
			db.close( );
		}
		cursor.close( );
	}

	public void onStop()
	{
		super.onStop( );
		// if(db != null && helper != null) {
		// helper.close();
		// db.close();
		// }
	}

	// The system calls this function when the User press the back arrow on the
	// keyboard
	@Override
	public void onBackPressed()
	{
		backWasClicked = true;
		onBtnStopClicked( null );
		super.onBackPressed( );
		mySensorManager.unregisterListener( LightSensorListener );
		mySensorManager = null;
		return;
	}

	// Reads the data out of the database and shows the User the number of
	// iterations, what he has to done
	private void dataFromDatabase()
	{
		cursor = db.rawQuery( "SELECT * FROM Goals WHERE Type=? LIMIT 1", new String[ ] { currentSportart } );

		if( cursor.getCount( ) == 1 )
		{
			cursor.moveToFirst( );
			reachedAmount = Integer.parseInt( cursor.getString( 3 ) );
			intendedAmount = Integer.parseInt( cursor.getString( 4 ) );
			cursor.close( );
		}

		if( reachedAmount == intendedAmount )
		{
			btnStart.setEnabled( false );
			showToast( "You already did enough training for this month" );
		}
		else
		{
			exerciseAmount = intendedAmount / 20;
			tvLightAmount.setText( "" + exerciseAmount );
		}

	}

	// Write to Database
	public void dataToDatabase()
	{
		if( !wroteInDB )
		{
			SQLiteDatabase db = helper.getWritableDatabase( );
			ContentValues values = new ContentValues( );
			ContentValues val2 = new ContentValues( );
			int unixTime = (int) ( System.currentTimeMillis( ) / 1000L );

			Cursor c = db.rawQuery( "SELECT * FROM Goals WHERE Type=? LIMIT 1", new String[ ] { currentSportart } );
			c.moveToFirst( );
			int reached = Integer.parseInt( c.getString( 3 ) );

			values.put( "Type", currentSportart );
			values.put( "Count", totalCount );
			values.put( "Date", unixTime );
			values.put( "Time", time );
			val2.put( "Reached", reached + totalCount );
			db.insert( "Activities", null, values );
			db.update( "Goals", val2, "Type=?", new String[ ] { currentSportart } );
			wroteInDB = true;
		}
	}

	// Show toast once
	public void showToast( String text )
	{
		if( lastToast != null )
		{
			lastToast.cancel( );
		}
		lastToast = Toast.makeText( LightSensorSportArtsActivity.this, text, Toast.LENGTH_SHORT );
		lastToast.show( );
	}

	// The user calls the function , when he clicks on Start Button.
	public void onBtnStartClicked( View view )
	{
		btnStart.setEnabled( false );
		btnStop.setEnabled( true );
		btnStart.setTextColor( Color.GRAY );
		btnStop.setTextColor( Color.GREEN );
		time = System.currentTimeMillis( ) / 1000L;
		calculateLimitValues( );
		countPressUp = 0;
		countSize = 0;
		textShowCount.setText( countPressUp + "" );
		textShowCount.setTextSize( 20 + countSize );
		start = true;
		wroteInDB = false;
	}

	// The user calls the function , after clicking on Stop Button.
	public void onBtnStopClicked( View view )
	{
		btnStart.setEnabled( true );
		btnStop.setEnabled( false );
		btnStart.setTextColor( Color.GRAY );
		btnStop.setTextColor( Color.GRAY );
		totalCount = +countPressUp;
		start = false;
		dataToDatabase( );
		if( !backWasClicked )
		{
			// //Opens a camera Intent and the User can take a exhausted
			// picture
			image = (ImageView) findViewById( R.id.image );
			Intent i = new Intent( LightSensorSportArtsActivity.this, CameraView.class );
			startActivityForResult( i, 999 );
		}
	}

	// Calculate the two light borders in dependency to the current light.
	public void calculateLimitValues()
	{
		calibrateValue = lastDataLightSensor;
		// caluclate. The User types in two values, how far the two borders
		// should be away from the current light
		int max = 100 + MAX_CALIBRATE;
		int min = 100 - MIN_CALIBRATE;
		light_limit_max = ( calibrateValue * max ) / 100; // calculate the max
														  // and min border
		light_limit_min = ( calibrateValue * min ) / 100;
	}

	private final SensorEventListener LightSensorListener = new SensorEventListener( )
	{
		@Override
		public void onAccuracyChanged( Sensor sensor, int accuracy )
		{

		}

		// The Systems calls this function, when the system realize a light
		// change
		@Override
		public void onSensorChanged( SensorEvent event )
		{
			lastDataLightSensor = event.values[ 0 ];

			if( !calibratedAlready )
			{
				calculateLimitValues( );
				calibratedAlready = true;
			}

			if( event.sensor.getType( ) == Sensor.TYPE_LIGHT )
			{
				// Is waiting for a while. The counter consider the time, when
				// the head is touching the device
				// And the User can not practice more than the trainigsplan says
				if( start && countPressUp < exerciseAmount + 1 && event.values[ 0 ] <= light_limit_min && ( System.currentTimeMillis( ) - lastUpdateTime ) >= ( WAIT_SEC * 1000 ) )
				{
					change = true;
				}

				if( change && event.values[ 0 ] >= light_limit_max )
				{
					change = false;
					increaseCounter( );
				}
			}
		}

		private void increaseCounter()
		{

			countPressUp++;
			textShowCount.setText( countPressUp + "" );
			if( countSize < 15 )
			{
				countSize++;
				textShowCount.setTextSize( 20 + countSize * 10 );

			}
			playSound( );
			lastUpdateTime = System.currentTimeMillis( );

		}

		private void playSound()
		{

			if( countPressUp + reachedAmount < intendedAmount )
			{
				if( countPressUp == exerciseAmount )
				{
					mPlayer = MediaPlayer.create( LightSensorSportArtsActivity.this, R.raw.one_more );
					mPlayer.start( );
				}
				else if( countPressUp > exerciseAmount )
				{
					mPlayer = MediaPlayer.create( LightSensorSportArtsActivity.this, R.raw.nice_one );
					mPlayer.start( );

					onBtnStopClicked( null );
				}
			}
			else
			{
				mPlayer = MediaPlayer.create( LightSensorSportArtsActivity.this, R.raw.nice_one );
				mPlayer.start( );
				onBtnStopClicked( null );
			}

		}

	};

	@Override
	protected void onActivityResult( int requestCode, int resultCode, Intent data )
	{

	}


	public static ImageView image;

	public void onPause()
	{
		super.onPause( );
		if( mPlayer != null )
		{
			mPlayer.release( );
		}
	}

}
